function upload2ByThis(target, successFunc, failureFunc) {
  let file = target.files[0];
  let progress = target.getAttribute("data-progress");
  if (progress == undefined) {
    window.progressTemp = undefined;
  } else {
    window.progressTemp = $(progress);
  }
  window.successFunc = successFunc;
  window.failureFunc = failureFunc;

  getFileMd5(file, function (file, md5) {
    progressThis(1, 0);
    let url = '/files/upload/pre';
    let body = { "md5": md5 };
    let tag = "from server";
    preuploadFile(url, body, function (response) {
      if (response.flag) {
        var result = {};
        result.code = 2;
        result.data = response.data;
        eventCallBack(result, tag);
      } else {
        let formData = new FormData();
        formData.append("file", file);
        formData.append("md5", md5);
        uploadFile('/files/upload', formData, tag);
      }
    });

  }, function (file) {
    console.warn('oops, something went wrong.');
  }, function (file, p) {
    progressThis(1, p);
  });
}

function uploadFile(url, formData, tag) {
  $.ajax({
    type: "POST",
    url: url,
    data: formData,
    processData: false,
    contentType: false,
    xhr: function () {
      var xhr = $.ajaxSettings.xhr();
      if (xhr.upload) {
        //处理进度条的事件
        xhr.upload.addEventListener("progress", function (e) {
          var curr = e.loaded;
          var total = e.total;
          var process = Math.floor((curr / total) * 100);

          var result = {};
          result.code = 0;
          result.data = process
          eventCallBack(result, tag);
        }, false);
      }

      //加载完成的事件
      xhr.addEventListener("load", function (e) {
        var result = {};
        result.code = 1;
        eventCallBack(result, tag);
      }, false);

      //加载出错的事件
      xhr.addEventListener("error", function (e) {
        var result = {};
        result.code = -1;
        eventCallBack(result, tag);
      }, false);

      //加载取消的事件
      xhr.addEventListener("abort", function (e) {
        var result = {};
        result.code = -2;
        eventCallBack(result, tag);
      }, false);

      return xhr;
    },
    success: function (data) {
      var result = {};
      result.code = 2;
      result.data = data;
      eventCallBack(result, tag);
    },
    failure: function (data) {
      console.info(data);
      var result = {};
      result.code = -1;
      result.data = jqXHR.responseText;
      eventCallBack(result, tag);
    },
    error: function (jqXHR) {
      console.info(jqXHR);
      var result = {};
      result.code = -1;
      result.data = jqXHR.responseText;
      eventCallBack(result, tag);
    }
  });
};

function eventCallBack(result, tag) {
  if (result.code == -2) {
    // 上传被取消
  } else if (result.code == -1) {
    // 上传出错
    if (window.failureFunc == undefined) {
      toast.failure(result.msg);
    } else {
      window.failureFunc(result.data)
    }
    progressThis(1, 0);
  } if (result.code == 0) {
    // 上传进度
    progressThis(2, result.data);
  } else if (result.code == 1) {
    // 上传完成
    progressThis(2, 0);
  } else if (result.code == 2) {
    // 上传成功
    if (window.successFunc != undefined) {
      // 返回结果
      window.successFunc("/encrypts/files/" + result.data.uuid, result.data);
    } else {
      toast.success(result.data.msg, reload);
    }
  }
}

function preuploadFile(url, data, successFunc) {
  $.ajax({
    type: 'POST',
    url: url,
    data: JSON.stringify(data),
    contentType: "application/json",
    success: function (data, textStatus, jqXHR) {
      successFunc(data);
    },
    error: function (jqXHR) {
	  console.info(jqXHR);
	  if (jqXHR.status == 403) {
		toast.failure(jqXHR.responseJSON.message);
	  }
    }
  });
};

function progressThis(i, p) {
  if (window.progressTemp != undefined) {
    if (i == 1) {
      window.progressTemp.css("width", p + "%");
      if (p == 0) {
        window.progressTemp.text("0%");
      } else {
        window.progressTemp.text("正在准备" + p + "%");
      }
    } else if (i == 2) {
      window.progressTemp.css("width", p + "%");
      if (p == 0) {
        setTimeout(() => window.progressTemp.text("0%"), 1000);
      } else {
        window.progressTemp.text("正在上传" + p + "%");
      }
    }
  }
}

function getFileMd5(file, complete, error, progress) {
  let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
    chunkSize = 2097152, // Read in chunks of 2MB
    chunks = Math.ceil(file.size / chunkSize),
    currentChunk = 0,
    spark = new SparkMD5.ArrayBuffer(),
    fileReader = new FileReader();

  fileReader.onload = function (e) {
    spark.append(e.target.result); // Append array buffer
    currentChunk++;
    let md5Progress = Math.floor((currentChunk / chunks) * 100);
    if (progress) {
      progress(file, md5Progress);
    }
    if (currentChunk < chunks) {
      loadNext();
    } else {
      if (complete) {
        complete(file, spark.end());
      }
    }
  };
  fileReader.onerror = function () {
    if (error) {
      error(file)
    }
  };

  function loadNext() {
    let start = currentChunk * chunkSize,
      end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
    fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
  }

  loadNext();
}